#include "libstatus.h"
#include <QVBoxLayout>
#include <QThreadPool>
#include <QLabel>

static inline QSlider* makeSlider(int min, int max);

LibStatus::LibStatus(QWidget *parent) :
    QWidget(parent)
{
    setLayout(new QVBoxLayout);

    _bookCount = new QProgressBar();
    _readerWriterCount = new  QProgressBar();
    _pendingCount = new QProgressBar();

    layout()->addWidget(_bookCount);
    layout()->addWidget(_readerWriterCount);
    layout()->addWidget(_pendingCount);

    _readInterval = makeSlider(0, 1000);
    _writeInterval = makeSlider(0, 1000);
    _maxBooksCount = makeSlider(1, 1000);
    _readersCount = makeSlider(0, 100);
    _writersCount = makeSlider(0, 100);

    layout()->addWidget(new QLabel("Read Interval:"));
    layout()->addWidget(_readInterval);
    layout()->addWidget(new QLabel("Write Interval:"));
    layout()->addWidget(_writeInterval);
    layout()->addWidget(new QLabel("Max Numbers of books:"));
    layout()->addWidget(_maxBooksCount);
    layout()->addWidget(new QLabel("Reader count:"));
    layout()->addWidget(_readersCount);
    layout()->addWidget(new QLabel("Writer count:"));
    layout()->addWidget(_writersCount);

    connect(&_library, SIGNAL(booksCountChanged(int)), _bookCount, SLOT(setValue(int)));
    _bookCount->setFormat("%v/%m");

    connect(&_library, SIGNAL(waitCountChanged(int)), this, SLOT(setWaitCount(int)));
    _pendingCount->setFormat("");
    _readerWriterCount->setFormat("");

    connect(_readInterval, SIGNAL(valueChanged(int)), &_library, SLOT(setReadInterval(int)));
    connect(_writeInterval, SIGNAL(valueChanged(int)), &_library, SLOT(setWriteInterval(int)));
    connect(_maxBooksCount, SIGNAL(valueChanged(int)), _bookCount, SLOT(setMaximum(int)));
    connect(_maxBooksCount, SIGNAL(valueChanged(int)), &_library, SLOT(setBooksMaxCount(int)));
    connect(_readersCount, SIGNAL(valueChanged(int)), this, SLOT(setReaderCount(int)));
    connect(_writersCount, SIGNAL(valueChanged(int)), this, SLOT(setWriterCount(int)));


    _readInterval->setValue(100);
    _writeInterval->setValue(100);
    _maxBooksCount->setValue(100);
    _writersCount->setValue(2);
    _readersCount->setValue(7);
}

void LibStatus::setWaitCount(int waitCount)
{
    _pendingCount->setValue(waitCount);
    _readerWriterCount->setValue(_readerWriterCount->maximum() - waitCount);
}

template<typename T>
void LibStatus::changeWorkersCount(QVector<T*> &workers, int count)
{
    QThreadPool* pool =  QThreadPool::globalInstance();
    int diff = count - workers.size();
    if (diff > 0) {
        for (int i = 0; i < diff; ++i) {
            workers.push_back(new T(_library));
            pool->start(workers.back());
        }
    } else {
        while (diff < 0) {
            workers.back()->stop();
            workers.pop_back();
            diff++;
        }
    }

    _pendingCount->setMaximum(_writers.size() + _readers.size());
    _readerWriterCount->setMaximum(_writers.size() + _readers.size());
    QThreadPool::globalInstance()->setMaxThreadCount(_writers.size() + _readers.size());
}

void LibStatus::setReaderCount(int count)
{
    changeWorkersCount(_readers, count);
}

void LibStatus::setWriterCount(int count)
{
    changeWorkersCount(_writers, count);
}

static inline QSlider* makeSlider(int min, int max)
{
    QSlider* slider = new QSlider(Qt::Horizontal);
    slider->setRange(min, max);
//    slider->setValue(value);
    return slider;
}
